package com.fingard.diagnostics;

import java.util.ArrayList;
import java.util.HashMap;

import com.fingard.FGBiz;
import com.fingard.io.FileHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

/**脱敏处理*/
public class Desensitize {
	
	/**敏感词，item.for属性指定具体线路代码
	 * 第一层key是for-transType，第二层key是节点名，
	 * HashMap<for-transType, HashMap<节点名,mode>>
	 * 值如HashMap<"CMB01-1908", HashMap<"ACCNBR","1">>
	 * */
	private HashMap<String, HashMap<String,String>> hashSensWords;
	/**    <!-- 日志脱敏配置
    item.enable属性：是否启用
    item.for属性指定全局或者某个线路代码
    item.transType节点，每个item含一个<transType>，配置相应的TransType，可配置多个，如1908,1944，*代表全部
    item.sensWords节点，每个item可含多个<sensWords>，配置需要脱敏的节点名称
    item.sensWords.mode属性，配置脱敏模式，
    					模式1：保留两头字符各4个字符，中间替换为*，如果总长度不足16，两头字符各不超过1/4，
    					即16位及以上，保留两头各4个字符，12位时，保留两头各3个字符
    					模式2：最多仅保留第一个字符，如果字符串本身就一个字符，即替换为*
     -->
     	<item enable="true" for="*" readme="全局">
	    <transType readme="如1908,1944，*代表全部">*</transType>
	    <sensWords mode="1" readme="敏感节点">PayAct,RecAct,CertNum,CellPhone,Mobile</sensWords>
	    <sensWords mode="2" readme="敏感节点">PayName,RecName</sensWords>
	</item>
	<item enable="true" for="CMB01" readme="">
	    <transType>*</transType>
	    <sensWords mode="1" readme="敏感节点">ACCNBR,CDTEAC,DBTACC,CRTACC,RPYACC,GSBACC</sensWords>
	    <sensWords mode="2" readme="敏感节点">CDTNAM,CRTNAM,RPYNAM,GSBNAM,CLTNAM</sensWords>
	</item>
	 * @throws Exception 
     *
     */
	public Desensitize(String pCfgPath) throws Exception{
		
		if(FileHelper.existFile(pCfgPath)){
			String strConfig = FileHelper.readFileText(pCfgPath, "utf-8");
            XmlTextReader xmlReader = new XmlTextReader(strConfig);
            
            HashMap<String, HashMap<String,String>> tmpSensWords = new HashMap<String, HashMap<String,String>>();
            
            while(xmlReader.read("/config/item")){
            	XElement eachItem = xmlReader.readedXElement;
            	if(eachItem.getAttrValueAsBool("enable")){//启用
            		String attrFor = eachItem.getAttrValue("for");
            		XElement xeTT = eachItem.getSingleChild("transType");
        			if(xeTT != null){
        				String key1 = attrFor+"-"+xeTT.innerText;
        				HashMap<String,String> eachMap;
        				if(tmpSensWords.containsKey(key1)){
        					eachMap = tmpSensWords.get(key1);
        				}else{
        					eachMap = new HashMap<String,String>();
        					tmpSensWords.put(key1, eachMap);
        				}
        				ArrayList<XElement> xeList = eachItem.getChildList("sensWords");
        				for(XElement eachWords : xeList){
        					String mode = eachWords.getAttrValue("mode");
        					String[] detailWds = eachWords.innerText.split(",");
        					for(String eachStr : detailWds){
        						eachMap.put(eachStr.trim(), mode);
        					}
        				}
        				String[] transTypes = xeTT.innerText.split(",");
        				if(transTypes.length > 1){//多个，复用同一个map
        					for(int i=0;i<transTypes.length;i++){
        						String kkey = attrFor+"-"+transTypes[i];
        						tmpSensWords.put(kkey, eachMap);
        					}
        				}
        			}
            	}
            }
            
            hashSensWords = tmpSensWords;
		}else{
			FGBiz.limitMsg.error("Desensitize", "日志脱敏配置文件"+pCfgPath+"不存在");
		}
	}
	
	
	/**日志脱敏*/
	public String DesensitizeBankLog(String pBankCode, String pTransType, String pLogStr){
		if(hashSensWords == null || hashSensWords.size() == 0){
			return pLogStr;
		}
		//第一层key是for-transType
		String[] keys = new String[]{pBankCode+"-"+pTransType, pBankCode+"-*", "*-"+pTransType, "*-*"};
		ArrayList<HashMap<String,String>> mapList = new ArrayList<HashMap<String,String>>();
		for(int i=0;i<keys.length;i++){
			if(hashSensWords.containsKey(keys[i])){
				mapList.add(hashSensWords.get(keys[i]));
			}
		}
		if(mapList.size() == 0){
			return pLogStr;
		}
		StringBuilder sb = new StringBuilder(pLogStr.length());
		int offset = 0;//判断是否为敏感字段名的偏移量
		int appendOffset=0;//添加字符串到sb的偏移量
		while(offset<pLogStr.length()){
			int idx1 = pLogStr.indexOf('<', offset);
			if(idx1>=0){
				int idx2 = pLogStr.indexOf('>', idx1);
				if(idx2>idx1){
					String nodeName = pLogStr.substring(idx1, idx2).trim();//取得日志中的节点名
					if(nodeName.contains(" ")){
						nodeName = nodeName.split(" ")[0];
					}
					//判断是否为敏感节点
					boolean isSens = false;
					String deMode = "";
					for(int i=0;i<mapList.size();i++){
						if(mapList.get(i).containsKey(nodeName)){
							isSens = true;
							deMode = mapList.get(i).get(nodeName);
						}
					}
					if(isSens){
						
						if("2".equals(deMode)){
							
						}
					}
				}else{
					break;
				}
			}else{
				break;
			}
		}
		return sb.toString();
	}
}
